QuickOPC User's Guide and Reference
OPC UA File Transfer Client
Features > Specialized Client Objects > OPC UA File Transfer > OPC UA File Transfer Client
In This Topic

The specialized EasyUAFileTransferClient object allows you to make OPC UA file transfer operations easily, without having to deal with details of the corresponding OPC UA service or method calls. You do not have study the OPC UA specifications and write low-level code to make each method call; all this knowledge is already encapsulated in the specialized client object for you. For example, you can directly call methods such as OpenFile or ReadFile, without having to know the method Ids and how to put together the array of method arguments and dissect the result.

This article describes API levels 2 and 2+ for OPC UA File Transfer (the EasyUAFileTransferClient Class together with the extension methods defined in the IEasyUAFileTransferExtension Class). For an overview of API levels, see OPC UA File Transfer.

The features discussed here, or some of them, may not be available in all editions of the product. Check the Product Editions page for differences between the editions. The trial license has all features enabled (and is limited in period for which it provides valid data), but licenses for specific commercial editions may have functionality limitations.
This functionality is not available under (or the text does not apply to) COM development platform.

Operations overview

Methods (the basic set, i.e. API level 2, IEasyUAFileTransferClient Interface) are available to:

Extensions methods (i.e. API level 2+, in IEasyUAFileTransferExtension Class) are used to expose more overloads (different structure of arguments) to the above methods, and to provide more complex functionality. Also, the extension methods provide distinction between files and directories where the OPC UA File Transfer does not: For example, if you specifically want to move a file, you need to be sure that you do not move a directory that happens to have the same name. The "raw" OPC UA File Transfer do not make this distinction. Other extension methods are available to:

You may want to look at OPC UA File Transfers internals in order to understand a bit of what is happening "under the hood".

Error model

The error model of OPC UA File Transfer Client object is as described in Error Model in imperative programming. In short, leaving aside usage errors (incorrect arguments or invalid operations, which can be prevented and do not appear in correctly written code), most methods throw only UAException. Methods that return OperationResult (or an array of them) do not indicate errors by throwing exceptions at all, but instead, you can inspect the Exception Property after the method has returned.

File handles

An OPC UA file handle encapsulates an access request to the OPC UA file. It is represented by the UAFileHandle Class, and returned by some of the methods, such as CreateFile Method or OpenFile Method. The handle is then subsequently used in methods like ReadFile or WriteFile. When you are finished with accessing the OPC UA file, your code should call the CloseFile Method with the handle, and also dispose of the OPC file handle object using its IDisposable.Dispose Method (this can be achieved in C# or VB.NET by the means of the "using" statement).

Dealing with OPC UA file handles is somewhat cumbersome, and you may want to consider using OPC UA File Streams for accessing the file data instead. 

Reading and writing file data

In order to read from and/or write to a file:

  1. Open or create the file and obtain the file handle: The OpenFile MethodCreateFile Method, their extension methods with a different structure of arguments, or the CreateAndOpenFile Method or CreateOrOpenFile Method extension methods.
  2. If needed, use the file position to navigate inside the file: The GetFilePosition Method, the SetFilePosition Method.
  3. Perform the actual reads and writes: ReadFile MethodWriteFile Method.
  4. When finished, close the file handle and dispose of the file handle object: CloseFile Method, IDisposable.Dispose Method.

Note that when using methods from API level 2 and 2+, QuickOPC automatically provides read/write chunking, but no file data buffering (see OPC UA File Transfer internals for more information). Use OPC UA File Streams if file data buffering is needed.

Reading 

The example below shows how to read different sections from an OPC UA file, using the file transfer client.

// Shows how to read different sections from an OPC UA file, using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
    class ReadAndSetFilePosition
    {
        public static void Main1()
        {
            // Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            UAEndpointDescriptor endpointDescriptor = "opc.tcp://localhost:48030";

            // A node that represents an instance of OPC UA FileType object.
            UANodeDescriptor fileNodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile";
            
            // Instantiate the file transfer client object
            var fileTransferClient = new EasyUAFileTransferClient();

            // Open the file, read two separate sections of it, and close it.
            try
            {
                Console.WriteLine("Opening file...");
                using (UAFileHandle fileHandle = fileTransferClient.OpenFile(endpointDescriptor, fileNodeDescriptor, UAOpenFileModes.Read))
                {
                    Console.WriteLine("Reading first file section...");
                    byte[] bytes1 = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, length:16);
                    Console.WriteLine($"First section: {BitConverter.ToString(bytes1)}");

                    Console.WriteLine("Reading second file section...");
                    byte[] bytes2 = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, length: 10);
                    Console.WriteLine($"Second section: {BitConverter.ToString(bytes2)}");

                    Console.WriteLine("Setting file position...");
                    fileTransferClient.SetFilePosition(endpointDescriptor, fileNodeDescriptor, fileHandle, position:100);

                    Console.WriteLine("Reading third file section...");
                    byte[] bytes3 = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, length: 20);
                    Console.WriteLine($"Third section: {BitConverter.ToString(bytes3)}");

                    Console.WriteLine("Closing file...");
                    fileTransferClient.CloseFile(endpointDescriptor, fileNodeDescriptor, fileHandle);
                }
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            Console.WriteLine("Finished...");
        }
    }
}
# Shows how to read different sections from an OPC UA file, using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from System import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')

# A node that represents an instance of OPC UA FileType object.
fileNodeDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile')

# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()

# Open the file, read two separate sections of it, and close it.
fileHandle = None
try:
    print('Opening file...')
    fileHandle = fileTransferClient.OpenFile(endpointDescriptor, fileNodeDescriptor, UAOpenFileModes.Read)

    print('Reading first file section...')
    bytes1 = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, 16)    # length
    print('First section: ', BitConverter.ToString(bytes1), sep='')

    print('Reading second file section...')
    bytes2 = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, 10)    # length
    print('Second section: ', BitConverter.ToString(bytes2), sep='')

    print('Setting file position...')
    fileTransferClient.SetFilePosition(endpointDescriptor, fileNodeDescriptor, fileHandle, 100) # position

    print('Reading third file section...')
    bytes3 = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, 20)    # length
    print('Third section: ', BitConverter.ToString(bytes3), sep='')

    print('Closing file...')
    fileTransferClient.CloseFile(endpointDescriptor, fileNodeDescriptor, fileHandle)

except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

finally:
    fileHandle and fileHandle.Dispose()

print()
print('Finished.')
' Shows how to read different sections from an OPC UA file, using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace FileTransfer._EasyUAFileTransferClient

    Friend Class ReadAndSetFilePosition

        Public Shared Sub Main1()

            ' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            Dim endpointDescriptor As UAEndpointDescriptor = "opc.tcp://localhost:48030"

            ' A node that represents an instance of OPC UA FileType object.
            Dim fileNodeDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile"

            ' Instantiate the file transfer client object
            Dim fileTransferClient = New EasyUAFileTransferClient

            ' Open the file, read two separate sections of it, and close it.
            Try
                Console.WriteLine("Opening file...")
                Using fileHandle As UAFileHandle = fileTransferClient.OpenFile(endpointDescriptor, fileNodeDescriptor, UAOpenFileModes.Read)
                    Console.WriteLine("Reading first file section...")
                    Dim bytes1 As Byte() = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, 16)
                    Console.WriteLine($"First section: {BitConverter.ToString(bytes1)}")

                    Console.WriteLine("Reading second file section...")
                    Dim bytes2 As Byte() = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, 10)
                    Console.WriteLine($"Second section: {BitConverter.ToString(bytes2)}")

                    Console.WriteLine("Setting file position...")
                    fileTransferClient.SetFilePosition(endpointDescriptor, fileNodeDescriptor, fileHandle, 100)

                    Console.WriteLine("Reading third file section...")
                    Dim bytes3 As Byte() = fileTransferClient.ReadFile(endpointDescriptor, fileNodeDescriptor, fileHandle, 20)
                    Console.WriteLine($"Third section: {BitConverter.ToString(bytes3)}")

                    Console.WriteLine("Closing file...")
                    fileTransferClient.CloseFile(endpointDescriptor, fileNodeDescriptor, fileHandle)
                End Using
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            Console.WriteLine("Finished...")
        End Sub
    End Class
End Namespace

 

If you want to read the whole contents of a file at once, you can use extension methods described in OPC UA File Streams.

Writing 

The example below shows how to write data into a section of an OPC UA file, using the file transfer client.

// Shows how to write data into a section of an OPC UA file, using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

using System;
using System.Text;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
    class WriteFile
    {
        public static void Main1()
        {
            // Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            UAEndpointDescriptor endpointDescriptor = "opc.tcp://localhost:48030";

            // A node that represents an instance of OPC UA FileType object.
            UANodeDescriptor fileNodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile";
            
            // Instantiate the file transfer client object
            var fileTransferClient = new EasyUAFileTransferClient();

            // Open the file, write a section of it, and close it.
            try
            {
                Console.WriteLine("Opening file...");
                using (UAFileHandle fileHandle = fileTransferClient.OpenFile(endpointDescriptor, fileNodeDescriptor, 
                    UAOpenFileModes.Read | UAOpenFileModes.Write))
                {
                    Console.WriteLine("Writing file section...");
                    byte[] data = Encoding.UTF8.GetBytes("TEXT FROM FILE TRANSFER CLIENT EXAMPLE. Demonstrates writing a section of a file. <<<");
                    fileTransferClient.WriteFile(endpointDescriptor, fileNodeDescriptor, fileHandle, data);

                    Console.WriteLine("Closing file...");
                    fileTransferClient.CloseFile(endpointDescriptor, fileNodeDescriptor, fileHandle);
                }
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            Console.WriteLine();
            Console.WriteLine("Finished...");
        }
    }
}
# Shows how to write data into a section of an OPC UA file, using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from System import *
from System.Text import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Extensions import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')
endpointDescriptor = UAEndpointDescriptorExtension.WithUserNameIdentity(endpointDescriptor,'john', 'master')

# A node that represents an instance of OPC UA FileType object.
fileNodeDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile')

# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()

# Prevent prompt to trust the server certificate (INSECURE, used just for smooth example flow).
EasyUAClient.SharedParameters.EngineParameters.CertificateAcceptancePolicy.TrustEndpointUrlString(
    endpointDescriptor.UrlString)

# Open the file, write a section of it, and close it.
fileHandle = None
try:
    print('Opening file...')
    fileHandle = fileTransferClient.OpenFile(endpointDescriptor, fileNodeDescriptor,
                                             UAOpenFileModes.Read | UAOpenFileModes.Write)

    print('Writing file section...')
    data = Encoding.UTF8.GetBytes('TEXT FROM FILE TRANSFER CLIENT EXAMPLE. Demonstrates writing a section of a file. '
                                  '<<<')
    fileTransferClient.WriteFile(endpointDescriptor, fileNodeDescriptor, fileHandle, data)

    print('Closing file...')
    fileTransferClient.CloseFile(endpointDescriptor, fileNodeDescriptor, fileHandle)

except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

finally:
    fileHandle and fileHandle.Dispose()

print()
print('Finished.')
' Shows how to write data into a section of an OPC UA file, using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

Imports System.Text
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace FileTransfer._EasyUAFileTransferClient

    Friend Class WriteFile

        Public Shared Sub Main1()

            ' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            Dim endpointDescriptor As UAEndpointDescriptor = "opc.tcp://localhost:48030"

            ' A node that represents an instance of OPC UA FileType object.
            Dim fileNodeDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile"

            ' Instantiate the file transfer client object
            Dim fileTransferClient = New EasyUAFileTransferClient

            ' Open the file, write a section of it, and close it.
            Try
                Console.WriteLine("Opening file...")
                Using fileHandle As UAFileHandle = fileTransferClient.OpenFile(endpointDescriptor, fileNodeDescriptor,
                    UAOpenFileModes.Read Or UAOpenFileModes.Write)
                    Console.WriteLine("Writing file section...")
                    Dim data As Byte() = Encoding.UTF8.GetBytes("TEXT FROM FILE TRANSFER CLIENT EXAMPLE. Demonstrates writing a section of a file. <<<")
                    fileTransferClient.WriteFile(endpointDescriptor, fileNodeDescriptor, fileHandle, data)

                    Console.WriteLine("Closing file...")
                    fileTransferClient.CloseFile(endpointDescriptor, fileNodeDescriptor, fileHandle)
                End Using
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            Console.WriteLine()
            Console.WriteLine("Finished...")
        End Sub
    End Class
End Namespace

 

If you want to write the whole contents of a file at once, you can use extension methods described in OPC UA File Streams

Creating, deleting, copying and moving files and directories

You will find following (and more) functionality in this group of methods:

The FindXXXX methods (except for FindOrCreateXXXX methods) return a null reference when the specified object does not exist. The GetXXXX methods return an error (throw an exception) if the specified object does not exist.

The example below shows how to create and delete OPC UA directories, using the file transfer client.

// Shows how to create and delete OPC UA directories, using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.Extensions;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
    class CreateDirectoryAndDelete
    {
        public static void Main1()
        {
            // Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            var endpointDescriptor = new UAEndpointDescriptor("opc.tcp://localhost:48030")
                .WithUserNameIdentity("john", "master");

            // An object that aggregates an OPC UA file system.
            UANodeDescriptor objectDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files";

            // Create a random number generator - will be used for file/directory names.
            var random = new Random();
            
            // Instantiate the file transfer client object
            var fileTransferClient = new EasyUAFileTransferClient();

            // Create two directories, and one nested directory, and delete the first one.
            try
            {
                // The file system node is a root directory of the file system.
                Console.WriteLine("Getting file system...");
                UANodeDescriptor fileSystemNodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor);

                string directoryName1 = "MyDirectory1-" + random.Next();
                Console.WriteLine($"Creating first directory, '{directoryName1}'...");
                UANodeId directoryNodeId1 = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1);
                Console.WriteLine($"Node Id of the first directory: {directoryNodeId1}");

                string directoryName2 = "MyDirectory2-" + random.Next();
                Console.WriteLine($"Creating second directory, '{directoryName2}'...");
                UANodeId directoryNodeId2 = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName2);
                Console.WriteLine($"Node Id of the second directory: {directoryNodeId2}");

                string nestedDirectoryName = "MyDirectory3-" + random.Next();
                Console.WriteLine($"Creating nested directory, '{nestedDirectoryName}'...");
                // Note how directoryNodeId2 (a parent directory) is passed as the 2nd argument to the CreateDirectory method.
                UANodeId nestedDirectoryNodeId = fileTransferClient.CreateDirectory(endpointDescriptor, directoryNodeId2, nestedDirectoryName);
                Console.WriteLine($"Node Id of the nested directory: {nestedDirectoryNodeId}");

                // At this moment, the directory structure we have created looks like this:
                // * MyDirectory1
                // * MyDirectory2
                // * * MyDirectory3

                Console.WriteLine("Deleting the first directory...");
                fileTransferClient.DeleteDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            Console.WriteLine("Finished...");
        }
    }
}
# Shows how to create and delete OPC UA directories, using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import random

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Extensions import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')
endpointDescriptor = UAEndpointDescriptorExtension.WithUserNameIdentity(endpointDescriptor,'john', 'master')

# An object that aggregates an OPC UA file system.
objectDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files')

# Create a random number generator - will be used for file/directory names.
random = random.Random()

# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()

# Prevent prompt to trust the server certificate (INSECURE, used just for smooth example flow).
EasyUAClient.SharedParameters.EngineParameters.CertificateAcceptancePolicy.TrustEndpointUrlString(
    endpointDescriptor.UrlString)

# Create two directories, and one nested directory, and delete the first one.
try:
    # The file system node is a root directory of the file system.
    print('Getting file system...')
    fileSystemNodeDescriptor = IEasyUAFileTransferExtension.GetFileSystem(fileTransferClient,
                                                                          endpointDescriptor, objectDescriptor)

    directoryName1 = 'MyDirectory1-' + str(random.randint(0, 999_999_999))
    print("Creating first directory, '", directoryName1, "'...", sep='')
    directoryNodeId1 = fileTransferClient.CreateDirectory(endpointDescriptor,
                                                          fileSystemNodeDescriptor,
                                                          directoryName1)
    print('Node Id of the first directory: ', directoryNodeId1, sep='')

    directoryName2 = 'MyDirectory2-' + str(random.randint(0, 999_999_999))
    print("Creating second directory, '", directoryName2, "'...", sep='')
    directoryNodeId2 = fileTransferClient.CreateDirectory(endpointDescriptor,
                                                          fileSystemNodeDescriptor,
                                                          directoryName2)
    print('Node Id of the second directory: ', directoryNodeId1, sep='')

    nestedDirectoryName = 'MyDirectory3-' + str(random.randint(0, 999_999_999))
    print("Creating nested directory, '", nestedDirectoryName, "'...", sep='')
    # Note how directoryNodeId2 (a parent directory) is passed as the 2nd argument to the CreateDirectory method.
    nestedDirectoryNodeId = fileTransferClient.CreateDirectory(endpointDescriptor,
                                                               UANodeDescriptor(directoryNodeId2),
                                                               nestedDirectoryName)
    print('Node Id of the nested directory: ', nestedDirectoryNodeId, sep='')

    # At this moment, the directory structure we have created looks like this:
    # * MyDirectory1
    # * MyDirectory2
    # * * MyDirectory3

    print('Deleting the first directory...')
    IEasyUAFileTransferExtension.DeleteDirectory(fileTransferClient,
                                                 endpointDescriptor, fileSystemNodeDescriptor, directoryName1)

except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

print()
print('Finished.')
' Shows how to create and delete OPC UA directories, using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.Extensions
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace FileTransfer._EasyUAFileTransferClient

    Friend Class CreateDirectoryAndDelete

        Public Shared Sub Main1()

            ' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            Dim endpointDescriptor As UAEndpointDescriptor =
                New UAEndpointDescriptor("opc.tcp://localhost:48030") _
                .WithUserNameIdentity("john", "master")

            ' An object that aggregates an OPC UA file system.
            Dim objectDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files"

            ' Create a random number generator - will be used for file/directory names.
            Dim random = New Random

            ' Instantiate the file transfer client object
            Dim fileTransferClient = New EasyUAFileTransferClient

            ' Create two directories, and one nested directory, and delete the first one.
            Try
                ' The file system node is a root directory of the file system.
                Console.WriteLine("Getting file system...")
                Dim fileSystemNodeDescriptor As UANodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor)

                Dim directoryName1 As String = "MyDirectory1-" & random.Next()
                Console.WriteLine($"Creating first directory, '{directoryName1}'...")
                Dim directoryNodeId1 As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1)
                Console.WriteLine($"Node Id of the first directory: {directoryNodeId1}")

                Dim directoryName2 As String = "MyDirectory2-" & random.Next()
                Console.WriteLine($"Creating second directory, '{directoryName2}'...")
                Dim directoryNodeId2 As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName2)
                Console.WriteLine($"Node Id of the second directory: {directoryNodeId2}")

                Dim nestedDirectoryName As String = "MyDirectory3-" & random.Next()
                Console.WriteLine($"Creating nested directory, '{nestedDirectoryName}'...")
                ' Note how directoryNodeId2 (a parent directory) Is passed as the 2nd argument to the CreateDirectory method.
                Dim nestedDirectoryNodeId As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, directoryNodeId2, nestedDirectoryName)
                Console.WriteLine($"Node Id of the nested directory: {nestedDirectoryNodeId}")

                ' At this moment, the directory structure we have created looks Like this
                ' * MyDirectory1
                ' * MyDirectory2
                ' * * MyDirectory3

                Console.WriteLine("Deleting the first directory...")
                fileTransferClient.DeleteDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1)
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            Console.WriteLine("Finished...")
        End Sub
    End Class
End Namespace

 

The example below shows how to copy an OPC UA file, using the file transfer client.

// Shows how to copy an OPC UA file, using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.Extensions;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
    class Copy
    {
        public static void File1()
        {
            // Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            var endpointDescriptor = new UAEndpointDescriptor("opc.tcp://localhost:48030")
                .WithUserNameIdentity("john", "master");

            // An object that aggregates an OPC UA file system.
            UANodeDescriptor objectDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files";

            // Create a random number generator - will be used for file/directory names.
            var random = new Random();

            // Instantiate the file transfer client object
            var fileTransferClient = new EasyUAFileTransferClient();

            // Create a file, and a directory. Then, copy the file into the directory.
            try
            {
                // The file system node is a root directory of the file system.
                Console.WriteLine("Getting file system...");
                UANodeDescriptor fileSystemNodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor);

                string fileName = "MyFile-" + random.Next();
                Console.WriteLine($"Creating file, '{fileName}'...");
                UANodeId fileNodeId = fileTransferClient.CreateFile(endpointDescriptor, fileSystemNodeDescriptor, fileName);
                Console.WriteLine($"Node Id of the file: {fileNodeId}");

                string directoryName = "MyDirectory-" + random.Next();
                Console.WriteLine($"Creating directory, '{directoryName}'...");
                UANodeId directoryNodeId = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName);
                Console.WriteLine($"Node Id of the directory: {directoryNodeId}");

                Console.WriteLine("Copying the file...");
                fileTransferClient.CopyFile(endpointDescriptor, fileSystemNodeDescriptor, fileNodeId, directoryNodeId);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            Console.WriteLine("Finished...");
        }
    }
}
# Shows how to copy an OPC UA file, using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import random

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Extensions import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')
endpointDescriptor = UAEndpointDescriptorExtension.WithUserNameIdentity(endpointDescriptor,'john', 'master')

# An object that aggregates an OPC UA file system.
objectDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files')

# Create a random number generator - will be used for file/directory names.
random = random.Random()

# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()

# Prevent prompt to trust the server certificate (INSECURE, used just for smooth example flow).
EasyUAClient.SharedParameters.EngineParameters.CertificateAcceptancePolicy.TrustEndpointUrlString(
    endpointDescriptor.UrlString)

# Create a file, and a directory. Then, copy the file into the directory.
try:
    # The file system node is a root directory of the file system.
    print('Getting file system...')
    fileSystemNodeDescriptor = IEasyUAFileTransferExtension.GetFileSystem(fileTransferClient,
                                                                          endpointDescriptor, objectDescriptor)

    fileName = 'MyFile-' + str(random.randint(0, 999_999_999))
    print("Creating file, '", fileName, "'...", sep='')
    fileNodeId = IEasyUAFileTransferExtension.CreateFile(fileTransferClient,
                                                         endpointDescriptor, fileSystemNodeDescriptor, fileName)
    print('Node Id of the file: ', fileNodeId, sep='')

    directoryName = 'MyDirectory-' + str(random.randint(0, 999_999_999))
    print("Creating directory, '", directoryName, "'...", sep='')
    directoryNodeId = fileTransferClient.CreateDirectory(endpointDescriptor,
                                                         fileSystemNodeDescriptor,
                                                         directoryName)
    print('Node Id of the directory: ', directoryNodeId, sep='')

    print('Copying the file...')
    IEasyUAFileTransferExtension.CopyFile(fileTransferClient,
                                          endpointDescriptor, fileSystemNodeDescriptor, fileNodeId, directoryNodeId)
    # If you want browse for directories, use the BrowseDirectories method instead.

except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

print()
print('Finished.')
' Shows how to copy an OPC UA file, using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.Extensions
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace FileTransfer._EasyUAFileTransferClient

    Friend Class Copy

        Public Shared Sub File1()

            ' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            Dim endpointDescriptor As UAEndpointDescriptor =
                New UAEndpointDescriptor("opc.tcp://localhost:48030") _
                .WithUserNameIdentity("john", "master")

            ' An object that aggregates an OPC UA file system.
            Dim objectDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files"

            ' Create a random number generator - will be used for file/directory names.
            Dim random = New Random

            ' Instantiate the file transfer client object
            Dim fileTransferClient = New EasyUAFileTransferClient

            ' Create a file, and a directory. Then, copy the file into the directory.
            Try
                ' The file system node is a root directory of the file system.
                Console.WriteLine("Getting file system...")
                Dim fileSystemNodeDescriptor As UANodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor)

                Dim fileName As String = "MyFile-" & random.Next()
                Console.WriteLine($"Creating file, '{fileName}'...")
                Dim fileNodeId As UANodeId = fileTransferClient.CreateFile(endpointDescriptor, fileSystemNodeDescriptor, fileName)
                Console.WriteLine($"Node Id of the file: {fileNodeId}")

                Dim directoryName As String = "MyDirectory-" & random.Next()
                Console.WriteLine($"Creating directory, '{directoryName}'...")
                Dim directoryNodeId As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName)
                Console.WriteLine($"Node Id of the directory: {directoryNodeId}")

                Console.WriteLine("Copying the file...")
                fileTransferClient.CopyFile(endpointDescriptor, fileSystemNodeDescriptor, fileNodeId, directoryNodeId)
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            Console.WriteLine("Finished...")
        End Sub
    End Class
End Namespace

 

Navigation among files and directories

This group of methods provides following functionality:

Getting information about files and directories

This group of methods provides following (and more) operations:

The example below shows how to get OPC UA file properties (such as its size or writable status), using the file transfer client.

// Shows how to get OPC UA file properties (such as its size or writable status), using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
    class GetFileProperties
    {
        public static void Main1()
        {
            // Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            UAEndpointDescriptor endpointDescriptor = "opc.tcp://localhost:48030";

            // A node that represents an instance of OPC UA FileType object.
            UANodeDescriptor fileNodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile";
            
            // Instantiate the file transfer client object
            var fileTransferClient = new EasyUAFileTransferClient();

            // Get properties of a specified file.
            UAFileProperties fileProperties;
            Console.WriteLine("Getting file properties...");
            try
            {
                fileProperties = fileTransferClient.GetFileProperties(endpointDescriptor, fileNodeDescriptor);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Display result
            Console.WriteLine();
            Console.WriteLine($"MimeType: {fileProperties.MimeType}");
            Console.WriteLine($"OpenCount: {fileProperties.OpenCount}");
            Console.WriteLine($"Size: {fileProperties.Size}");
            Console.WriteLine($"UserWritable: {fileProperties.UserWritable}");
            Console.WriteLine($"Writable: {fileProperties.Writable}");
            Console.WriteLine($"Timestamp: {fileProperties.Timestamp}");

            Console.WriteLine();
            Console.WriteLine("Finished...");
        }
    }
}
# Shows how to get OPC UA file properties (such as its size or writable status), using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')

# A node that represents an instance of OPC UA FileType object.
fileNodeDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile')

# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()

# Get properties of a specified file.
try:
    print('Getting file properties...')
    fileProperties = IEasyUAFileTransferExtension.GetFileProperties(fileTransferClient,
                                                                    endpointDescriptor, fileNodeDescriptor)
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Display result.
print()
print('MimeType: ', fileProperties.MimeType, sep='')
print('OpenCount: ', fileProperties.OpenCount, sep='')
print('Size: ', fileProperties.Size, sep='')
print('UserWritable: ', fileProperties.UserWritable, sep='')
print('Writable: ', fileProperties.Writable, sep='')
print('Timestamp: ', fileProperties.Timestamp, sep='')

print()
print('Finished.')
' Shows how to get OPC UA file properties (such as its size or writable status), using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace FileTransfer._EasyUAFileTransferClient

    Friend Class GetFileProperties

        Public Shared Sub Main1()

            ' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            Dim endpointDescriptor As UAEndpointDescriptor = "opc.tcp://localhost:48030"

            ' A node that represents an instance of OPC UA FileType object.
            Dim fileNodeDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files.TextFile"

            ' Instantiate the file transfer client object
            Dim fileTransferClient = New EasyUAFileTransferClient

            ' Get properties of a specified file.
            Dim fileProperties As UAFileProperties
            Console.WriteLine("Getting file properties...")
            Try
                fileProperties = fileTransferClient.GetFileProperties(endpointDescriptor, fileNodeDescriptor)
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Display result
            Console.WriteLine()
            Console.WriteLine($"MimeType: {fileProperties.MimeType}")
            Console.WriteLine($"OpenCount: {fileProperties.OpenCount}")
            Console.WriteLine($"Size: {fileProperties.Size}")
            Console.WriteLine($"UserWritable: {fileProperties.UserWritable}")
            Console.WriteLine($"Writable: {fileProperties.Writable}")
            Console.WriteLine($"Timestamp: {fileProperties.Timestamp}")

            Console.WriteLine()
            Console.WriteLine("Finished...")
        End Sub
    End Class
End Namespace

 

The example below shows how to browse for OPC UA files, using the file transfer client.

// Shows how to browse for OPC UA files, using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

using System;
using System.Collections.Generic;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Extensions;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
    class BrowseFiles
    {
        public static void Main1()
        {
            // Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            var endpointDescriptor = new UAEndpointDescriptor("opc.tcp://localhost:48030")
                .WithUserNameIdentity("john", "master");

            // An object that aggregates an OPC UA file system.
            UANodeDescriptor objectDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files";

            // Create a random number generator - will be used for file/directory names.
            var random = new Random();
            
            // Instantiate the file transfer client object
            var fileTransferClient = new EasyUAFileTransferClient();

            // Create two files, and then browse the directory that contains them.
            Dictionary<string, UANodeDescriptor> fileNodeDescriptorDictionary;
            try
            {
                // The file system node is a root directory of the file system.
                Console.WriteLine("Getting file system...");
                UANodeDescriptor fileSystemNodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor);

                string fileName1 = "MyFile1-" + random.Next();
                Console.WriteLine($"Creating first file, '{fileName1}'...");
                fileTransferClient.CreateFile(endpointDescriptor, fileSystemNodeDescriptor, fileName1);

                string fileName2 = "MyFile2-" + random.Next();
                Console.WriteLine($"Creating second file, '{fileName2}'...");
                fileTransferClient.CreateFile(endpointDescriptor, fileSystemNodeDescriptor, fileName2);

                Console.WriteLine("Browsing for files...");
                fileNodeDescriptorDictionary = fileTransferClient.BrowseFiles(endpointDescriptor, fileSystemNodeDescriptor);
                // If you want browse for directories, use the BrowseDirectories method instead.
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Display result
            Console.WriteLine();
            foreach (KeyValuePair<string, UANodeDescriptor> pair in fileNodeDescriptorDictionary)
                Console.WriteLine(pair);
            
            Console.WriteLine();
            Console.WriteLine("Finished...");
        }
    }
}
# Shows how to browse for OPC UA files, using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import random

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Extensions import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')
endpointDescriptor = UAEndpointDescriptorExtension.WithUserNameIdentity(endpointDescriptor,'john', 'master')

# An object that aggregates an OPC UA file system.
objectDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files')

# Create a random number generator - will be used for file/directory names.
random = random.Random()

# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()

# Prevent prompt to trust the server certificate (INSECURE, used just for smooth example flow).
EasyUAClient.SharedParameters.EngineParameters.CertificateAcceptancePolicy.TrustEndpointUrlString(
    endpointDescriptor.UrlString)

# Create two files, and then browse the directory that contains them.
try:
    # The file system node is a root directory of the file system.
    print('Getting file system...')
    fileSystemNodeDescriptor = IEasyUAFileTransferExtension.GetFileSystem(fileTransferClient,
                                                                          endpointDescriptor, objectDescriptor)

    fileName1 = 'MyFile1-' + str(random.randint(0, 999_999_999))
    print("Creating first file, '", fileName1, "'...", sep='')
    IEasyUAFileTransferExtension.CreateFile(fileTransferClient, endpointDescriptor, fileSystemNodeDescriptor, fileName1)

    fileName2 = 'MyFile2-' + str(random.randint(0, 999_999_999))
    print("Creating second file, '", fileName1, "'...", sep='')
    IEasyUAFileTransferExtension.CreateFile(fileTransferClient, endpointDescriptor, fileSystemNodeDescriptor, fileName2)

    print('Browsing for files...')
    fileNodeDescriptorDictionary = IEasyUAFileTransferExtension.BrowseFiles(fileTransferClient,
                                                                            endpointDescriptor,
                                                                            fileSystemNodeDescriptor)
    # If you want browse for directories, use the BrowseDirectories method instead.

except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Display results.
print()
for pair in fileNodeDescriptorDictionary:
    print(pair)

print()
print('Finished.')
' Shows how to copy an OPC UA file, using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.Extensions
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace FileTransfer._EasyUAFileTransferClient

    Friend Class BrowseFiles

        Public Shared Sub Main1()

            ' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
            Dim endpointDescriptor As UAEndpointDescriptor =
                New UAEndpointDescriptor("opc.tcp://localhost:48030") _
                .WithUserNameIdentity("john", "master")

            ' An object that aggregates an OPC UA file system.
            Dim objectDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files"

            ' Create a random number generator - will be used for file/directory names.
            Dim random = New Random

            ' Instantiate the file transfer client object
            Dim fileTransferClient = New EasyUAFileTransferClient

            ' Create two files, and then browse the directory that contains them.
            Dim fileNodeDescriptorDictionary As IReadOnlyDictionary(Of String, UANodeDescriptor)
            Try
                ' The file system node is a root directory of the file system.
                Console.WriteLine("Getting file system...")
                Dim fileSystemNodeDescriptor As UANodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor)

                Dim fileName1 As String = "MyFile1-" & random.Next()
                Console.WriteLine($"Creating first file, '{fileName1}'...")
                fileTransferClient.CreateFile(endpointDescriptor, fileSystemNodeDescriptor, fileName1)

                Dim fileName2 As String = "MyFile2-" & random.Next()
                Console.WriteLine($"Creating second file, '{fileName2}'...")
                fileTransferClient.CreateFile(endpointDescriptor, fileSystemNodeDescriptor, fileName2)

                Console.WriteLine("Browsing for files...")
                fileNodeDescriptorDictionary = fileTransferClient.BrowseFiles(endpointDescriptor, fileSystemNodeDescriptor)
                ' If you want browse for directories, use the BrowseDirectories method instead.
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Display result
            Console.WriteLine()
            For Each pair In fileNodeDescriptorDictionary
                Console.WriteLine(pair)
            Next pair

            Console.WriteLine()
            Console.WriteLine("Finished...")
        End Sub
    End Class
End Namespace

 

See Also

Examples - OPC UA File Transfer

Knowledge Base